﻿//========================================================= 
/**@file commandline.h
 * @brief 命令行调用工具
 * 
 * @date 2018-09-21   14:40:54
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_COMMANDLINE_H_
#define _LIBZHOUYB_COMMANDLINE_H_
//--------------------------------------------------------- 
#include "../../include/Base.h"

#include <vector>
#include <boost/filesystem.hpp>
#include <boost/process.hpp>
#include <boost/process/windows.hpp>

#include "../../extension/ability/win_helper/WinHelper.h"
using zhou_yb::extension::ability::WinHelper;
//--------------------------------------------------------- 
namespace zhou_yb {
namespace wrapper {
namespace zabbix_extractor {
//--------------------------------------------------------- 
/**
 * @brief 调用命令行并获取stdout输出
 * @date 2018-09-21 14:41
 */
class commandline_monitor
{
public:
    typedef string value_type;

    static string pack_arguments(int argc, const char* argv[])
    {
        if(argc < 2) return "";
        string args = "";
        for(int i = 1; i < argc; ++i)
        {
            args += argv[i];
            args += ' ';
        }
        if(argc > 1) args.pop_back();
        return args;
    }

    static value_type execute(const char* cmdline)
    {
        boost::process::ipstream pipe_stream;
        std::string line = "";
        try {
            boost::process::child c(cmdline,
                boost::process::std_out > pipe_stream,
                boost::process::windows::hide);
            if(pipe_stream) std::getline(pipe_stream, line, static_cast<char>(EOF));
            c.wait();
        }
        catch(...) {}
        return line;
    }
    static value_type execute(int argc, const char* argv[])
    {
        string args = pack_arguments(argc, argv);
        if(args.length() < 1) return "";
        return execute(args.c_str());
    }
};
//--------------------------------------------------------- 
/**
 * @brief 工作目录切换器
 * @date 2018-12-10 15:25
 */
class work_directory_switcher
{
protected:
    char_t _path[_MAX_FNAME];
public:
    work_directory_switcher()
    {
        GetCurrentDirectory(_MAX_FNAME, _path);
    }
    virtual ~work_directory_switcher()
    {
        SetCurrentDirectory(_path);
    }
};
//--------------------------------------------------------- 
/**
 * @brief 通过命令行的方式启动程序
 * @date 2018-12-10 10:49
 */
class processcall_monitor
{
public:
    typedef string value_type;

    static bool change_work_directory(const char* cmdline, ByteBuilder& fullCmdLine)
    {
        ByteArray cmd(cmdline);
        size_t index = StringConvert::IndexOf(cmd, ' ');
        ByteBuilder dir = cmd.SubArray(0, index);
        ByteBuilder dirName;
        WinHelper::GetFullPath(dir.GetString(), fullCmdLine);
        if(index != SIZE_EOF)
        {
            fullCmdLine += cmd.SubArray(index);
        }
        WinHelper::ExtractFileName(dir, &dirName, NULL, NULL);
        if(dirName.GetLength() > 0)
        {
            CharConverter cvt;
            return Tobool(SetCurrentDirectory(cvt.to_char_t(dirName.GetString())));
        }
        return false;
    }

    static value_type execute(const char* cmdline)
    {
        try {
            ByteBuilder cmd;
            work_directory_switcher switcher;
            change_work_directory(cmdline, cmd);

            boost::process::child c(cmd.GetString());
            c.detach();
        }
        catch(...) {}
        return "0";
    }
    static value_type execute(int argc, const char* argv[])
    {
        string args = commandline_monitor::pack_arguments(argc, argv);
        if(args.length() < 1) return "";
        return execute(args.c_str());
    }
};
//--------------------------------------------------------- 
/**
 * @brief 通过命令行的方式在后台启动程序
 * @date 2018-12-10 10:49
 */
class processcall_background_monitor
{
public:
    typedef string value_type;

    static value_type execute(const char* cmdline)
    {
        try {
            ByteBuilder cmd;
            work_directory_switcher switcher;
            processcall_monitor::change_work_directory(cmdline, cmd);

            boost::process::child c(cmd.GetString() , boost::process::windows::hide);
            c.detach();
        }
        catch(...) {}
        return "0";
    }
    static value_type execute(int argc, const char* argv[])
    {
        string args = commandline_monitor::pack_arguments(argc, argv);
        if(args.length() < 1) return "";
        return execute(args.c_str());
    }
};
//--------------------------------------------------------- 
} // namespace zabbix_extractor 
} // namespace wrapper
} // namespace zhou_yb 
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_COMMANDLINE_H_
//========================================================= 